/***************************************************************************

Copyright (c) BizRulX. All rights reserved.

***************************************************************************/

using System;
using System.Globalization;
using Microsoft.VisualStudio.Shell;

namespace RuleXSoft.BizRuleCreator
{
    /// <summary>
    /// This attribute adds a File Extension for a Project System so that the Project
    /// will call IVsEditorFactoryNotify methods when an item of this type is added 
    /// or renamed.
    /// </summary>
    /// <remarks>
    /// For example:
    ///   [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\
    ///		{F184B08F-C81C-45F6-A57F-5ABD9991F28F}\FileExtensions\.addin]
    ///			"EditorFactoryNotify"="{FA3CD31E-987B-443A-9B81-186104E8DAC1}"
    /// </remarks>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    [System.Runtime.InteropServices.ComVisibleAttribute(false)]
    public sealed class EditorFactoryNotifyForProjectAttribute : RegistrationAttribute
    {
        #region Fields
		private Guid projectType;
		private Guid factoryType;
		private string fileExtension;
        #endregion

        #region Constructors
        /// <summary>
        /// Creates a new ProvideEditorFactoryNotifyForProject attribute to register a 
        /// file extension with a project. 
        /// </summary>
        /// <param name="projectType">The type of project; can be a Type, a GUID or a string representation of a GUID</param>
        /// <param name="factoryType">The type of factory; can be a Type, a GUID or a string representation of a GUID</param>
        /// <param name="fileExtension">The file extension the EditorFactoryNotify wants to handle</param>
        public EditorFactoryNotifyForProjectAttribute(object projectType, string fileExtension, object factoryType)
        {
            if (factoryType == null)
            {
                throw new ArgumentNullException(Resources.ParameterNameFactoryType, Resources.ExceptionMessageNullFactoryType);
            }
            if (projectType == null)
            {
                throw new ArgumentNullException(Resources.ParameterNameProjectType, Resources.ExceptionMessageNullProjectType);
            }

            this.fileExtension = fileExtension;

            // figure out what type of object they passed in and get the GUID from it
            // check stringType for String type
            string stringType = factoryType as string;
            if (stringType != null)
            {
                this.factoryType = new Guid(stringType);
            }
            else
            {
                Type typeType = factoryType as Type;
                if (typeType != null)
                {
                    this.factoryType = typeType.GUID;
                }
                else if (factoryType is Guid)
                {
                    this.factoryType = (Guid)factoryType;
                }
                else
                {
                    // factoryType is of unacceptable type
                    throw new ArgumentException( Resources.ExceptionMessageWrongParameterType, Resources.ParameterNameFactoryType);
                }
            }

            
            // figure out what type of object they passed in and get the GUID from it
            // check stringType for String type
            string stringProjectType = projectType as string;
            if (stringProjectType != null)
            {
                this.projectType = new Guid(stringProjectType);
            }
            else
            {
                Type typeProjectType = projectType as Type;
                if (typeProjectType != null)
                {
                    this.projectType = typeProjectType.GUID;
                }
                else if (projectType is Guid)
                {
                    this.projectType = (Guid)projectType;
                }
                else
                {
                    // factoryType is of unacceptable type
                    throw new ArgumentException(Resources.ExceptionMessageWrongParameterType, Resources.ParameterNameProjectType);
                }
            }
        }
        #endregion

        #region Properties
        /// <summary>
        /// Get the Guid representing the type of the editor factory
        /// </summary>
        //public Guid FactoryType
        public object FactoryType
        {
            get { return factoryType; }
        }

        /// <summary>
        /// Get the Guid representing the project type
        /// </summary>
        public object ProjectType
        {
            get { return projectType; }
        }

        /// <summary>
        /// Get or Set the extension of the XML files that support this view
        /// </summary>
        public string FileExtension
        {
            get { return fileExtension; }
        }

        /// <summary>
        /// Extension path within the registration context
        /// </summary>
        private string ProjectFileExtensionPath
        {
            get 
            { 
                return string.Format(CultureInfo.InvariantCulture, "Projects\\{0}\\FileExtensions\\{1}", projectType.ToString("B"), fileExtension); 
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Called to register this attribute with the given context.  The context
        /// contains the location where the registration information should be placed.
        /// It also contains other information such as the type being registered and path information.
        /// </summary>
        /// <param name="context">Given context to register in</param>
        public override void Register(RegistrationContext context)
        {
            if (context == null)
            {
            	throw new ArgumentNullException("context");
            }

            context.Log.WriteLine(String.Format(CultureInfo.CurrentCulture, "EditorFactoryNoftifyForProject: {0} Extension = {1}\n", projectType.ToString(), fileExtension));

            using (Key childKey = context.CreateKey(ProjectFileExtensionPath))
            {
                childKey.SetValue("EditorFactoryNotify", factoryType.ToString("B"));
            }
        }

        /// <summary>
        /// Unregister this file extension.
        /// </summary>
        /// <param name="context">Given context to unregister from</param>
        public override void Unregister(RegistrationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
			}

            context.RemoveKey(ProjectFileExtensionPath);
        }
        #endregion
    }
}
